﻿using System;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using MJD.Comunes.DtoEntidades;
using Recursos;

namespace Comunes.Validadores
{
    /// <summary>
    /// Clase que extiende las propiedades de los elementos del framework Silverlight para permitirle
    /// entre otras cosas validar el contenido
    /// </summary>
    public static class FrameworkElementExtension
    {

        #region Validadores de contenido

        /// <summary> Asigna el error a mostrar en el elemento </summary>
        /// <param name="frameworkElement">control ha ser validado</param>
        /// <param name="message">mensaje que se mostrar si no es valido el control</param>
        public static void SetValidation(this FrameworkElement frameworkElement, string message)
        {
            CustomValidation customValidation = new CustomValidation(message);
            Binding binding = new Binding("ValidationError")
            {
                Mode = BindingMode.TwoWay,
                NotifyOnValidationError = true,
                ValidatesOnExceptions = true,
                Source = customValidation
            };
            frameworkElement.SetBinding(Control.TagProperty, binding);
        }

        
        /// <summary> Muestra el error asignado al elemento </summary>
        /// <param name="frameworkElement">elemento ha ser validado</param>
        public static void RaiseValidationError(this FrameworkElement frameworkElement)
        {
            BindingExpression b =
            frameworkElement.GetBindingExpression(Control.TagProperty);
            if (b != null)
            {
                ((CustomValidation)b.DataItem).ShowErrorMessage = true;
                b.UpdateSource();
            }
        }


        /// <summary> Limpia cualquier error asociado a un elemento </summary>
        /// <param name="frameworkElement">elemento ha ser validado</param>
        public static void ClearValidationError(this FrameworkElement frameworkElement)
        {
            BindingExpression b =
            frameworkElement.GetBindingExpression(Control.TagProperty);
            if (b != null)
            {
                ((CustomValidation)b.DataItem).ShowErrorMessage = false;
                b.UpdateSource();
            }
        }


        /// <summary> Valida que un campo Email tenga la estructura correcta </summary>
        /// <param name="email">email ha validar</param>
        /// <returns>true si es valido false sino</returns>
        public static bool EmailValido(this string email)
        {
            const string expresionRegular = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
            Regex regex = new Regex(expresionRegular);

            return regex.IsMatch(email);
        }

        
        /// <summary> Valida que un string solo contenga numeros </summary>
        /// <param name="numero">numero ha validar</param>
        /// <returns>true si la cadena es puro numeros false sino</returns>
        public static bool SoloNumeros(this string numero)
        {
            const string expresionRegular = "^[0-9]+$";
            Regex regex = new Regex(expresionRegular);

            return regex.IsMatch(numero);
        }


        /// <summary> Valida que un numero esté en un rango valido </summary>
        /// <param name="numero">numero a validar que se encuentre dentro del rango</param>
        /// <param name="inicioRango">inicio del rango</param>
        /// <param name="finRango">fin del rango</param>
        /// <returns>true si se encuentra dentro del rango</returns>
        public static bool RangoValido(this string numero, int inicioRango, int finRango)
        {
            int entero = int.Parse(numero);

            return (entero >= inicioRango && entero <= finRango);
        }

#endregion

        #region Metodos para ampliacion de caracteristicas

        /// <summary>
        /// Amplia las propiedades de WriteableBitmap permitiendole exportar com oun arreglo de bytes el contenido
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public static byte[] ToByteArray(this WriteableBitmap bmp)
        {
            int[] p = bmp.Pixels;
            int len = p.Length * 4;
            byte[] result = new byte[len]; // ARGB
            Buffer.BlockCopy(p, 0, result, 0, len);
            return result;
        }


        /// <summary>
        /// Amplia las propiedades de WriteableBitmap permitiendole generar una imagen a partir de un arreglo de bytes
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="buffer"></param>
        public static void FromByteArray(this WriteableBitmap bmp, byte[] buffer)
        {
            Buffer.BlockCopy(buffer, 0, bmp.Pixels, 0, buffer.Length);
        }

        
        /// <summary>
        /// Extrae la informacion de un objeto DtoDireccion y la muestra en un string con formato
        /// </summary>
        /// <param name="sucursal">objeto a la que se quiere extraer la direccion</param>
        public static string LlevarAStringDireccionSucursal(DtoSucursal sucursal)
        {
            string strdireccion = string.Empty;

            if (!string.IsNullOrEmpty(sucursal.Calle))
                strdireccion += Strings.TextoCalleAvenida + sucursal.Calle;

            if (!string.IsNullOrEmpty(sucursal.Edificio))
                strdireccion += Strings.TextoEdifCasa + sucursal.Edificio;

            if (!string.IsNullOrEmpty(sucursal.Piso))
                strdireccion += Strings.TextoPiso + sucursal.Piso;

            if (!string.IsNullOrEmpty(sucursal.Apartamento))
                strdireccion += Strings.TextoApto + sucursal.Apartamento;
            
            if (!string.IsNullOrEmpty(sucursal.Urbanizacion))
                strdireccion += Strings.TextoUrbanizacion + sucursal.Urbanizacion;

            if (sucursal.Ciudad != null && !string.IsNullOrEmpty(sucursal.Ciudad.Nombre))
                strdireccion += ", " + sucursal.Ciudad.Nombre;

            return strdireccion;
        }


        ///// <summary>
        ///// Extrae la información de un objeto DtoDireccion y la muestra en un string con formato
        ///// </summary>
        ///// <param name="miembro"></param>
        //public static string NombreCompleto(this DtoMiembro miembro)
        //{
        //    return miembro.Nombre + " " + miembro.Apellido;
        //}


        #endregion
    }
}
